/*
//
//  What follows is the code for the game "frenchtoast", which uses tic-tac-toe
//  for the base rule set and adds a few new rules.  For example, there is a 
//  4x4 grid instead of a 3x3 one, and upon the start of the game you only get
//  a set number of moves.
//
*/

//headers
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include "SDL/SDL_mixer.h"
#include <sstream>

//screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;
//The frame rate
const int FRAMES_PER_SECOND = 20;

//the squares
char * squareID[4][4];

bool info = false;
bool isPlayerOnesTurn = true;
bool squareClicked = false;
bool musicIsPlaying = false;

char clickSquareIDx;
char clickSquareIDy;
int clickButtonX;
int clickButtonY;

//buttons
SDL_Rect new_game_button;
SDL_Rect how_button;
SDL_Rect about_button;
SDL_Rect info_button;
SDL_Rect music_next;
SDL_Rect music_play;
SDL_Rect music_stop;
SDL_Rect music_back;
//game-squares 
SDL_Rect square;

//surfaces
SDL_Surface *screen = NULL;
//images
SDL_Surface *background = NULL;
SDL_Surface *background_blend = NULL;
SDL_Surface *info_bubble = NULL;
SDL_Surface *info_over = NULL;
SDL_Surface *info_click = NULL;
SDL_Surface *info_background = NULL;
SDL_Surface *musicNext = NULL;
SDL_Surface *musicPause = NULL;
SDL_Surface *musicPlay = NULL;
SDL_Surface *musicStop = NULL;
SDL_Surface *musicBack = NULL;
SDL_Surface *playerTwoPiece = NULL;
SDL_Surface *playerOnePiece = NULL;
//text
SDL_Surface *titleBackground = NULL;
SDL_Surface *titleMessageA = NULL;
SDL_Surface *titleMessageB = NULL;
SDL_Surface *titleMessageC = NULL;
SDL_Surface *musicText = NULL;
SDL_Surface *playerOneScore = NULL;
SDL_Surface *playerTwoScore = NULL;
SDL_Surface *newGame = NULL;
SDL_Surface *howPlay = NULL;
SDL_Surface *about = NULL;
SDL_Surface *buttons = NULL;
SDL_Surface *buttons_pressed = NULL;
SDL_Surface *square_over = NULL;
SDL_Surface *buttons_med = NULL;
SDL_Surface *buttons_med_pressed = NULL;
SDL_Surface *square_click = NULL;
SDL_Surface *backgroundColor = NULL;
SDL_Surface *backgroundColor_med = NULL;
SDL_Surface *square_background = NULL;
SDL_Surface *version = NULL;
SDL_Surface *howText = NULL;
SDL_Surface *winnerMessage = NULL;

//temp
SDL_Surface *temp = NULL;

//events (keyboard/mouse/etc.)
SDL_Event event;

//text
TTF_Font *font = NULL;
TTF_Font *titleFont = NULL;
TTF_Font *titleFont2 = NULL;
TTF_Font *titleFont3 = NULL;
TTF_Font *winnerFont = NULL;

SDL_Color titleTextColor = { 52, 140, 27};
SDL_Color blackColor = { 0, 0, 0};
SDL_Color green_color = { 0, 255, 0};
SDL_Color blue_color = { 26, 102, 148 };
SDL_Color background_color = { 82, 82, 82 };

/* background music
the first array is the artist
the second array is the track name
the track we play will be picked by random, and the random number we pick will be the index of the arrays
so the index number of one array refers to the same index number of the other
for example, artist[5] is equal to the author of the track, and track[5] is equal to the name of that same track.
*/
const char* backgroundMusicAuthor[ ] = { "Saelynh",  "dubsoniq", "Andrew Vavrek", "subatomicglue", "JT Bruce" };
const char* backgroundMusicTrack[ ] = { "Speedfire", "Rainy Day", "Perish", "theme3", "Lucid" };

//background music
Mix_Music *music[ ] = { NULL, NULL, NULL, NULL, NULL };

int Random(int Max)
{
    return ( rand() % Max);
}

SDL_Surface *load_image( std::string filename )
{
            //temp storage
            SDL_Surface* loadedImage = NULL;
            
            //optimized image
            SDL_Surface* optimizedImage = NULL;
            
            //load image
            loadedImage = IMG_Load( filename.c_str() );
            
            //if nothing went wrong with loading...
            if( loadedImage != NULL )
            {
                //create optimized image
                optimizedImage = SDL_DisplayFormat( loadedImage );
                
                //free the old image
                SDL_FreeSurface( loadedImage );
                
                //if optimized nicely
                if( optimizedImage != NULL )
                {
                    //image transparency
                    SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ));
                }
            }
            
            //return optimized image
            return optimizedImage;
}

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
     //temp rectangle for offsets
     SDL_Rect offset;
     
     //offsets given to rectangle
     offset.x = x;
     offset.y = y;
     
     //blit the surface
     SDL_BlitSurface( source, clip, destination, &offset );
}

bool init()
{
     //initialize SDL
     if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
     {
         return false;
     }
     
     //set up the screen
     screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
     
     if( TTF_Init() == -1 )
     {
         return false;
     }
     //Initialize SDL_mixer
     if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 )
     { 
         return false; 
     }
     
     //if there are any errors...
     if( screen == NULL )
     {
         return false;
     }
     
     //set the titlebar text
     SDL_WM_SetCaption( "Ultimate Tic-Tac-Toe", NULL );
     
     //if all is set  up...
     return true;
}

bool load_files()
{
     //load images
     background = load_image( "images/background.png" );
     background_blend = load_image( "images/background_blend.png");
     info_bubble = load_image( "images/info-bubble.png");
     info_over = load_image( "images/info-over.png");
     info_click = load_image( "images/info-click.png");
     info_background = load_image("images/info-background.png");
     titleBackground = load_image( "images/titleScreen.png" );
     musicNext = load_image( "images/skip-forward.png");
     musicPause = load_image( "images/playback-pause.png");
     musicPlay = load_image( "images/playback-start.png");
     musicStop = load_image( "images/playback-stop.png");  
     musicBack = load_image( "images/skip-backward.png"); 
     buttons = load_image( "images/green.png"); 
     buttons_pressed = load_image( "images/blue.png");
     buttons_med = load_image( "images/green_med.png");
     buttons_med_pressed = load_image("images/blue_med.png"); 
     square_over = load_image("images/green_large.png");
     square_click = load_image("images/blue_large.png");
     square_background = load_image("images/background_large.png");
     backgroundColor = load_image( "images/background-color.png");
     backgroundColor_med = load_image( "images/background-color-med.png");
     playerTwoPiece = load_image("images/player-two.png");
     playerOnePiece = load_image("images/player-one.png");
     
     //load fonts
     font = TTF_OpenFont( "fonts/Larabiefont.ttf", 18 );
     titleFont = TTF_OpenFont( "fonts/Aetherfox.ttf", 36 );
     titleFont2 = TTF_OpenFont( "fonts/TeknikohlRemix01.ttf", 24);
     titleFont3 = TTF_OpenFont( "fonts/Larabiefont.ttf", 18);
     winnerFont = TTF_OpenFont( "fonts/TeknikohlRemix01.ttf", 36);
     
     //Load the music 
     music[0] = Mix_LoadMUS( "music/12 - Speedfire.ogg" );
     music[1] = Mix_LoadMUS( "music/01 - Rainy Day.ogg" );
     music[2] = Mix_LoadMUS( "music/vavrek.com_perish_1.0.ogg" );
     music[3] = Mix_LoadMUS( "music/04 - theme3.ogg" );
     music[4] = Mix_LoadMUS( "music/08 - Lucid.ogg" );
     
     //if anything didn't load, halt everything and the app will close
     if( (background == NULL) || (background_blend == NULL) || (info_bubble == NULL) || (info_over == NULL) || 
     (info_click == NULL) || (info_background == NULL) || (titleBackground == NULL) || (musicBack == NULL) ||
     (musicNext == NULL) || (musicPause == NULL) || (musicPlay == NULL) || (musicStop == NULL) || (buttons == NULL) || 
     (buttons_pressed == NULL) || (buttons_med == NULL) || (buttons_med_pressed == NULL) || (square_over == NULL) ||
     (square_click == NULL) || (square_background == NULL) || (backgroundColor == NULL) || (backgroundColor_med == NULL) || 
     (font == NULL) || (titleFont == NULL) || (titleFont2 == NULL) || (titleFont3 == NULL) || (playerTwoPiece == NULL) ||
     (playerOnePiece == NULL) || (winnerFont == NULL) || (music[0] == NULL) || (music[1] == NULL) || (music[2] == NULL) ||
     (music[3] == NULL) || (music[4] == NULL))
     {
         return false;
     }
     
     //if everything loaded nicely... 
     return true;
}

void clean_up()
{
     //free the images
     SDL_FreeSurface( background );
     SDL_FreeSurface(background_blend);
     SDL_FreeSurface(info_bubble);
     SDL_FreeSurface(info_over);
     SDL_FreeSurface(info_click);
     SDL_FreeSurface(info_background);
     SDL_FreeSurface(musicNext);
     SDL_FreeSurface(musicPause);
     SDL_FreeSurface(musicPlay);
     SDL_FreeSurface(musicStop);    
     SDL_FreeSurface(musicBack); 
     SDL_FreeSurface(titleBackground);
     SDL_FreeSurface(titleMessageA);
     SDL_FreeSurface(titleMessageB);
     SDL_FreeSurface(titleMessageC);
     SDL_FreeSurface(musicText);
     SDL_FreeSurface(playerOneScore);
     SDL_FreeSurface(playerTwoScore);
     SDL_FreeSurface(newGame);
     SDL_FreeSurface(howPlay);
     SDL_FreeSurface(about);
     SDL_FreeSurface(buttons);
     SDL_FreeSurface(buttons_pressed);
     SDL_FreeSurface(buttons_med);
     SDL_FreeSurface(buttons_med_pressed);
     SDL_FreeSurface(backgroundColor);
     SDL_FreeSurface(backgroundColor_med);
     SDL_FreeSurface(square_over);
     SDL_FreeSurface(square_click);
     SDL_FreeSurface(square_background);
     SDL_FreeSurface(version);
     SDL_FreeSurface(howText);
     SDL_FreeSurface(winnerMessage);
     
     SDL_FreeSurface(temp);
     
     //free the music
     Mix_FreeMusic( music[0] );
     Mix_FreeMusic( music[1] );
     Mix_FreeMusic( music[2] );
     Mix_FreeMusic( music[3] );
     Mix_FreeMusic( music[4] );
    
     TTF_CloseFont( font );
     TTF_CloseFont( titleFont );
     TTF_CloseFont( titleFont2 );
     TTF_CloseFont( titleFont3);
     TTF_CloseFont(winnerFont);
     
     TTF_Quit();
     SDL_Quit();
}

/*
  here, b represents whatever button is given us
  we will take that button, check to see if the mouse is over it,
  and display a green box if the mouse is over the button
*/
int buttonCheck( SDL_Rect b )
{
    int x = 0, y = 0;
    x = event.motion.x;
    y = event.motion.y;
    
    if(event.type == SDL_MOUSEBUTTONDOWN)
    {
         x = event.button.x;
         y = event.button.y;
         
         //check to see if mouse click was over a button
         if( ( x > b.x) && ( x < (b.x + b.w)) && (y > b.y) && (y < (b.y + b.h)))
         {
             
             if( event.button.button == SDL_BUTTON_LEFT)
             {
                 //save the position of the button that was clicked... we'll use this under "MOUSEBUTTONUP"
                 clickButtonX = b.x;
                 clickButtonY = b.y;
                 
                 //mouse was clicked, so make it blue
                 switch (b.w)
                 {
                        case 85:
                             apply_surface( b.x + 1, b.y + 1, buttons_pressed, background);
                             break;
                        case 93:
                             apply_surface( b.x + 1, b.y + 1, square_click, background);
                             break;
                        case 120:
                             apply_surface(b.x + 1, b.y + 1, info_click, info_bubble);
                             break;
                        case 130:
                             apply_surface( b.x + 1, b.y + 1, buttons_med_pressed, background);
                             break;
                 }
             }
         }
    }
    else if(event.type == SDL_MOUSEBUTTONUP)
    {
         x = event.button.x;
         y = event.button.y;
         
         //check to see if mouse was released over a button
         if( ( x > b.x) && ( x < (b.x + b.w)) && (y > b.y) && (y < (b.y + b.h)))
         {
             //check to see if the mouse was released over the same button it was clicked down on
             if(( clickButtonX == b.x) && (clickButtonY == b.y))
             {
                  //mouse was unclicked, so make it green again and return a number to
                  //tell the main loop that the mouse was clicked
                  switch (b.w)
                  {
                         case 32:
                              return 1;
                              break;
                         case 85:
                              apply_surface( b.x + 1, b.y + 1, buttons, background);
                              return 1;
                              break;
                         case 93:
                              apply_surface( b.x + 1, b.y + 1, square_over, background);
                              return 1;
                              break;
                         case 120:
                              apply_surface( b.x + 1, b.y + 1, info_background, info_bubble);
                              return 1;
                              break;
                         case 130:
                              apply_surface( b.x + 1, b.y + 1, backgroundColor_med, background);
                              return 1;
                              break;
                  }
             }
         }
    }
    
    //this will only happen as long as the mouse is NOT being held down,
    // that way, the mouse can be moved around without having the colors
    // go all crazy
    if( !SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(1))
    {
        if( event.type == SDL_MOUSEMOTION)
        {
            if( ( x > b.x) && ( x < (b.x + b.w)) && (y > b.y) && (y < (b.y + b.h)))
            {
                //cover area with green box, looks like it's highlighted
                switch (b.w)
                {
                       case 85:
                            apply_surface( b.x + 1, b.y + 1, buttons, background);
                            break;
                       case 93:
                            apply_surface( b.x + 1, b.y + 1, square_over, background);
                            break;
                       case 120:
                            apply_surface( b.x + 1, b.y + 1, info_over, info_bubble);
                            break;
                       case 130:
                            apply_surface( b.x + 1, b.y + 1, buttons_med, background);
                            break;
                }
            }
            else
            {
                //cover area with gray box, looks like normal
                switch (b.w)
                {
                       case 85:
                            apply_surface( b.x + 1, b.y + 1, backgroundColor, background);
                            break;
                       case 93:
                            apply_surface( b.x + 1, b.y + 1, square_background, background);
                            break;
                       case 120:
                            apply_surface( b.x + 1, b.y + 1, info_background, info_bubble);
                            break;
                       case 130:
                            apply_surface( b.x + 1, b.y + 1, backgroundColor_med, background);
                            break;
                }
            }
        }
    }
    return 0;
} 

void squareCheck ( )
{
     //squares
     for(int square_x = 3, squareIDx = 0; square_x <= 350; square_x += 95, squareIDx++)
     {
             //the middle two columns are one pixel larger, this compensates for that
             if( square_x == 193)
             {
                 square_x--;
             }
             
             for( int square_y = 102, squareIDy = 0; square_y <= 450; square_y += 94, squareIDy++)
             {
                  //instead of having a box for each square, there is just one box, and the for loop determines
                  // what that box is at any given moment
                  square.x = square_x;
                  square.y = square_y;
                  square.w = 93;
                  square.h = 95;
                             
                  //this will only happen as long as the 'how to play' or 'about' popup windows
                  // are NOT open, that way when they ARE open, the colors don't go crazy
                  if(!info)
                  {
                      int x = 0, y = 0;
                      
                      //again, make sure the mouse button is NOT down
                      if( !SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(1))
                      {
                          if( event.type == SDL_MOUSEMOTION)
                          {
                              x = event.motion.x;
                              y = event.motion.y;
                              if( ( x > square.x) && ( x < (square.x + square.w)) && (y > square.y) && (y < (square.y + square.h)))
                              {
                                  apply_surface( square.x + 1, square.y + 1, square_over, background);
                                  
                                  if(squareID[squareIDx][squareIDy] == "one")
                                  {
                                        apply_surface( square.x + 1, square.y + 1, playerOnePiece, background);
                                  }
                                  else if(squareID[squareIDx][squareIDy] == "two")
                                  {
                                       apply_surface( square.x + 1, square.y + 1, playerTwoPiece, background);
                                  }
                              }
                              else
                              {
                                  apply_surface( square.x + 1, square.y + 1, square_background, background);
                                  
                                  if(squareID[squareIDx][squareIDy] == "one")
                                  {
                                       apply_surface( square.x + 1, square.y + 1, playerOnePiece, background);
                                  }
                                  else if(squareID[squareIDx][squareIDy] == "two")
                                  {
                                       apply_surface( square.x + 1, square.y + 1, playerTwoPiece, background);
                                  }
                              }
                          }
                      }
                      
                      if(event.type == SDL_MOUSEBUTTONDOWN)
                      {
                           x = event.button.x;
                           y = event.button.y;
                           
                           if( ( x > square.x) && ( x < (square.x + square.w)) && (y > square.y) && (y < (square.y + square.h)))
                           {
                               if( event.button.button == SDL_BUTTON_LEFT)
                               {
                                   //mouse was clicked, so make it blue
                                   apply_surface( square.x + 1, square.y + 1, square_click, background);
                                   clickSquareIDx = squareIDx;
                                   clickSquareIDy = squareIDy;
                                   
                                   if(squareID[squareIDx][squareIDy] == "one")
                                   {
                                        apply_surface( square.x + 1, square.y + 1, playerOnePiece, background);
                                   }
                                   else if(squareID[squareIDx][squareIDy] == "two")
                                   {
                                        apply_surface( square.x + 1, square.y + 1, playerTwoPiece, background);
                                   }
                               }
                           }
                      }
                      else if(event.type == SDL_MOUSEBUTTONUP)
                      {
                           x = event.button.x;
                           y = event.button.y;
                           
                           if( ( x > square.x) && ( x < (square.x + square.w)) && (y > square.y) && (y < (square.y + square.h)))
                           {
                               if((clickSquareIDx == squareIDx) && (clickSquareIDy == squareIDy))
                               {
                                    //mouse is up - make square gray
                                    apply_surface(square.x + 1, square.y + 1, square_over, background);
                                    
                                    //if it's the player's turn, and the player doesn't already own this square, and if the ai doesn't own the square, 
                                    // then the player now owns it
                                    if( (isPlayerOnesTurn == true) && (squareID[squareIDx][squareIDy] != "one") && (squareID[squareIDx][squareIDy] != "two"))
                                    {
                                        squareID[squareIDx][squareIDy] = "one";
                                        squareClicked = true;
                                        isPlayerOnesTurn = false;                  
                                    }
                                    else if( (isPlayerOnesTurn != true) && (squareID[squareIDx][squareIDy] != "one") && (squareID[squareIDx][squareIDy] != "two"))
                                    {
                                         
                                        squareID[squareIDx][squareIDy] = "two";
                                        squareClicked = true;
                                        isPlayerOnesTurn = true;  
                                    }
                                    
                                    if(squareID[squareIDx][squareIDy] == "one")
                                    {
                                         apply_surface(square.x + 1, square.y + 1, playerOnePiece, background);
                                    }
                                    else if(squareID[squareIDx][squareIDy] == "two")
                                    {
                                         apply_surface( square.x + 1, square.y + 1, playerTwoPiece, background);
                                    }
                               }
                           }
                           else
                           {
                               apply_surface(square.x + 1, square.y + 1, square_background, background);
                               
                               if(squareID[squareIDx][squareIDy] == "one")
                               {
                                    apply_surface(square.x + 1, square.y + 1, playerOnePiece, background);
                               }
                               else if(squareID[squareIDx][squareIDy] == "two")
                               {
                                    apply_surface( square.x + 1, square.y + 1, playerTwoPiece, background);
                               }
                           }
                      }
                  }
             }
     } 
}

int checkForWin()
{
    /*
       Here we're going to check for win scenarios.
       If a player controls an entire row, column, or diagnal,
       then that corresponding variable will take the value of 1 or 2, 
       to show who controls it.  That player wins.
    */
    int row1 = 0, row2 = 0, row3 = 0, row4 = 0;
    int col1 = 0, col2 = 0, col3 = 0, col4 = 0;
    int diagUpLeft = 0, diagUpRight = 0;
    const char* checkWin = "one";
    
    for(int doubleCheck = 0; doubleCheck < 2; doubleCheck++)
    {
            //this changes checkWin to player two after player one has 
            // already been checked, so they both can win
            if (doubleCheck == 1)
            {
                 checkWin = "two";
            }
            
            //check the diagonal from upper left to lower right
            if( (squareID[0][0] == checkWin) && (squareID[1][1] == checkWin) && (squareID[2][2] == checkWin) && (squareID[3][3] == checkWin))
            {
                if(checkWin == "one")
                {
                    diagUpLeft = 1;
                }
                else
                {
                    diagUpLeft = 2;
                }
            }
            
            //check the diagonal from lower left to upper right
            if( (squareID[0][3] == checkWin) && (squareID[1][2] == checkWin) && (squareID[2][1] == checkWin) && (squareID[3][0] == checkWin))
            {
                if(checkWin == "one")
                {
                    diagUpRight = 1;
                }
                else
                {
                    diagUpRight = 2;
                }
            }            
            
            //check the rows
            for( int x = 0; x < 4; x++)
            {
                 if ( (squareID[x][0] == checkWin) && (squareID[x][1] == checkWin) && (squareID[x][2] == checkWin) && (squareID[x][3] == checkWin))
                 {
                      if(x == 0)
                      {
                           if(checkWin == "one")
                           {
                                row1 = 1;
                           }
                           else
                           {
                               row1 = 2;
                           }
                      }
                      
                      if(x == 1)
                      {
                           if(checkWin == "one")
                           {
                               row2 = 1;
                           }
                           else
                           {
                               row2 = 2;
                           }
                      }
                      
                      if(x == 2)
                      {
                           if(checkWin == "one")
                           {
                               row3 = 1;
                           }
                           else
                           {
                               row3 = 2;
                           }                   
                      }
                      
                      if(x == 3)
                      {
                           if(checkWin == "one")
                           {
                               row4 = 1;
                           }
                           else
                           {
                               row4 = 2;
                           }                   
                      }                             
                 }
            }
            
            //check the columns
            for( int y = 0; y < 4; y++)
            {
                 if ( (squareID[0][y] == checkWin) && (squareID[1][y] == checkWin) && (squareID[2][y] == checkWin) && (squareID[3][y] == checkWin))
                 {
                      if(y == 0)
                      {
                           if(checkWin == "one")
                           {
                               col1 = 1;
                           }
                           else
                           {
                               col1 = 2;
                           }                   
                      }
                      
                      if(y == 1)
                      {
                           if(checkWin == "one")
                           {
                               col2 = 1;
                           }
                           else
                           {
                               col2 = 2;
                           }
                      }
                      
                      if(y == 2)
                      {
                           if(checkWin == "one")
                           {
                               col3 = 1;
                           }
                           else
                           {
                               col3 = 2;
                           }                   
                      }
                      
                      if(y == 3)
                      {
                           if(checkWin == "one")
                           {
                               col4 = 1;
                           }
                           else
                           {
                               col4 = 2;
                           }                   
                      }                             
                 }
            }
    }
    
    if( (row1 == 0) && (row2 == 0) && (row3 == 0) && (row4 == 0) && (col1 == 0) && (col2 == 0) && (col3 == 0) && (col4 == 0) && (diagUpLeft == 0) && (diagUpRight == 0))
    {
        return 0;
    }

    else if( (row1 == 1) || (row2 == 1) || (row3 == 1) || (row4 == 1) || (col1 == 1) || (col2 == 1) || (col3 == 1) || (col4 == 1) || (diagUpLeft == 1) || (diagUpRight == 1))
    {
        return 1;
    }

    else if( (row1 == 2) || (row2 == 2) || (row3 == 2) || (row4 == 2) || (col1 == 2) || (col2 == 2) || (col3 == 2) || (col4 == 2) || (diagUpLeft == 2) || (diagUpRight == 2))
    {
        return 2;
    }
}

int main( int argc, char* args[])
{
    //wait until user closes app
    bool quit = false;
    int atTitleScreen = 0;
    float currentPlayerOneScore = 0;
    float currentPlayerTwoScore = 0;
    char * info_type = 0;
    int RandSong = Random(5);        
    
    //initialize
    if( init() == false)
    {
        return 1;
    }
    
    //load files
    if( load_files() == false)
    {
        return 1;
    }
    
    //defined here to help stop run-time slowdown
    musicText = TTF_RenderText_Shaded( titleFont3, "Music Controls", blackColor, blue_color);
    newGame = TTF_RenderText_Solid( titleFont3, "New-Game", blackColor);
    version = TTF_RenderText_Shaded( titleFont3, "Version 1.01", blackColor, background_color);
    howPlay = TTF_RenderText_Solid( titleFont3, "How-to-Play", blackColor);
    about = TTF_RenderText_Solid( titleFont3, "About", blackColor);
    
    //main loop - as long as user hasn't quit yet
    while( quit == false )
    {
           new_game_button.x = 466;
           new_game_button.y = 242;
           new_game_button.w = 85;
           new_game_button.h = 25;
           how_button.x = 510;
           how_button.y = 33;
           how_button.w = 130;
           how_button.h = 34;
           about_button.x = 510;
           about_button.y = 67;
           about_button.w = 130;
           about_button.h = 34;
           info_button.x = 259;
           info_button.y = 320;
           info_button.w = 120;
           info_button.h = 30;           
           
           //music buttons
           music_back.x = ((260 - musicBack->w) * 1 / 5 + 380);
           music_back.y = ((30 - musicBack->h) / 2 + 430);
           music_back.w = musicBack->w;
           music_back.h = musicBack->h;
           music_next.x = ((260 - musicNext->w) * 4 / 5 + 380);
           music_next.y = ((30 - musicNext->h) / 2 + 430);
           music_next.w = musicNext->w;
           music_next.h = musicNext->h;
           music_stop.x = ((260 - musicStop->w) * 2 / 5 + 380);
           music_stop.y = ((30 - musicStop->h) / 2 + 430);
           music_stop.w = musicStop->w;
           music_stop.h = musicStop->h;
           music_play.x = ((260 - musicPlay->w) * 3 / 5 + 380);
           music_play.y = ((30 - musicPlay->h) / 2 + 430);
           music_play.w = musicPause->w;
           music_play.h = musicPause->h;       

           if( (Mix_PlayingMusic() == 0) && (musicIsPlaying == true) ) 
           {
			   RandSong++;
               if(RandSong == 5)
               {
				   RandSong = 0;
               }
               if( Mix_PlayMusic( music[RandSong], 0 ) == -1 ) 
               {
				   return 1; 
               }                               
           } 
           
           //if there's an event
           if( SDL_PollEvent( &event ))
           {
               if(!info)
               {
                        if( buttonCheck( new_game_button) != 0)
                        {
                            //add points to the score if there's a win
                            if(checkForWin() == 1)
                            {
                                currentPlayerOneScore++;
                            }
                            else if(checkForWin() == 2)
                            {
                                 currentPlayerTwoScore++;
                            }
                     
                            //clear all squares
                            for(int x = 0; x < 4; x++)
                            {
                                    for(int y = 0; y < 4; y++)
                                    {
                                            squareID[x][y] = NULL;
                                            isPlayerOnesTurn = true;
                                    }
                            }
                        }
                        
                        if(buttonCheck( how_button ) != 0)
                        {
                             info = true;
                             info_type = "how";
                        }
                        
                        if(buttonCheck( about_button) != 0 )
                        {
                             info = true;
                             info_type = "about";
                        }
                        
                        if(buttonCheck(music_back) != 0)
                        {
                            if( (Mix_PlayingMusic() == 1) || (Mix_PausedMusic() == 1) ) 
                            {
                                musicIsPlaying = true;
                                //to skip to the next song, we first stop, then start it again
                                Mix_HaltMusic();
                                RandSong--;
                                if(RandSong == -1)
                                {
                                    RandSong = 4;
                                }
                                if( Mix_PlayMusic( music[RandSong], 0 ) == -1 ) 
                                {
                                    return 1; 
                                }                               
                            }                                                         
                        }
                        
                        if(buttonCheck(music_next) != 0)
                        {
                            if( (Mix_PlayingMusic() == 1) || (Mix_PausedMusic() == 1) ) 
                            {
                                musicIsPlaying = true;
                                //to skip to the next song, we first stop, then start it again
                                Mix_HaltMusic();
                                RandSong++;
                                if(RandSong == 5)
                                {
                                    RandSong = 0;
                                }
                                if( Mix_PlayMusic( music[RandSong], 0 ) == -1 ) 
                                {
                                    return 1; 
                                }                               
                            }                             
                        }
                        
                        if(buttonCheck(music_stop) != 0)
                        {
                            //Stop the music 
                            Mix_HaltMusic();
                            musicIsPlaying = false;
                        }
                        
                        if(buttonCheck(music_play) != 0)
                        {
                            //If there is no music playing 
                            if( Mix_PlayingMusic() == 0 ) 
                            { 
                                musicIsPlaying = true; 
                                //Play the music 
                                if( Mix_PlayMusic( music[RandSong], 0 ) == -1 ) 
                                {                                      
                                    return 1; 
                                } 
                            }
                            //If music is being played 
                            else
                            { 
                                //If the music is paused 
                                if( Mix_PausedMusic() == 1 ) 
                                { 
                                    //Resume the music 
                                    Mix_ResumeMusic(); 
                                    musicIsPlaying = true;
                                } 
                                //If the music is playing 
                                else 
                                { 
                                     //Pause the music 
                                     Mix_PauseMusic(); 
                                     musicIsPlaying = false;
                                } 
                            }
                            
                        }
                        
               }
               
               //if key was pressed
               if( (event.type == SDL_KEYDOWN) || (event.type == SDL_MOUSEBUTTONDOWN))
               {
                   if( atTitleScreen == 0)
                   {
                       atTitleScreen++;
                   }
                   else if( atTitleScreen == 1)
                   {
                       atTitleScreen++;
                   }
               }
               
               //user closes window
               if(event.type == SDL_QUIT)
               {
                   //quit program
                   quit = true;
               }
           }
           
           if(atTitleScreen == 0)
           {
                apply_surface( (SCREEN_WIDTH - titleBackground->w)/2, (SCREEN_HEIGHT - titleBackground->h)/2, titleBackground, screen);
                titleMessageA = TTF_RenderText_Solid( titleFont3, "A", titleTextColor );
                apply_surface( (SCREEN_WIDTH - titleMessageA->w - titleBackground->w)/2, (SCREEN_HEIGHT - titleMessageA->h)/2 - 175, titleMessageA, screen);                            
                            
                titleMessageB = TTF_RenderText_Solid( titleFont2, "Manic", green_color );
                apply_surface( (SCREEN_WIDTH - titleMessageB->w - titleBackground->w)/2, (SCREEN_HEIGHT - titleMessageB->h)/2 - 160, titleMessageB, screen);
                titleMessageB = TTF_RenderText_Solid( titleFont2, "Depressive", green_color );
                apply_surface( (SCREEN_WIDTH - titleMessageB->w - titleBackground->w)/2, (SCREEN_HEIGHT - titleMessageB->h)/2 - 140, titleMessageB, screen);
                titleMessageB = TTF_RenderText_Solid( titleFont2, "Grave", green_color );
                apply_surface( (SCREEN_WIDTH - titleMessageB->w - titleBackground->w)/2, (SCREEN_HEIGHT - titleMessageB->h)/2 - 120, titleMessageB, screen);
                titleMessageB = TTF_RenderText_Solid( titleFont2, "Bunny", green_color );
                apply_surface( (SCREEN_WIDTH - titleMessageB->w - titleBackground->w)/2, (SCREEN_HEIGHT - titleMessageB->h)/2 - 100, titleMessageB, screen);

                titleMessageA = TTF_RenderText_Solid( titleFont3, "Production", titleTextColor );
                apply_surface( (SCREEN_WIDTH - titleMessageA->w - titleBackground->w)/2, (SCREEN_HEIGHT - titleMessageA->h)/2 - 80, titleMessageA, screen);
			    
                titleMessageC = TTF_RenderText_Shaded( titleFont3, "( Press Any Button To Begin )", green_color, blackColor);
                apply_surface( (SCREEN_WIDTH - titleMessageC->w) / 2, (SCREEN_HEIGHT - titleMessageC->h) / 2 + 200, titleMessageC, screen);
           }
           else if(atTitleScreen == 1)
           {
                SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 00, 00, 00 ) );
                titleMessageA = TTF_RenderText_Solid( titleFont, "ULTIMATE", titleTextColor );
                titleMessageB = TTF_RenderText_Solid( titleFont2, "Tic-Tac-Toe", green_color );
                titleMessageC = TTF_RenderText_Shaded( titleFont3, "( Press Any Button To Begin )", green_color, blackColor);
                apply_surface( (SCREEN_WIDTH - titleMessageA->w)/2, (SCREEN_HEIGHT - titleMessageA->h)/2 - 20, titleMessageA, screen);
                apply_surface( (SCREEN_WIDTH - titleMessageB->w)/2, (SCREEN_HEIGHT - titleMessageB->h)/2 + 20, titleMessageB, screen);
                apply_surface( (SCREEN_WIDTH - titleMessageC->w)/2, (SCREEN_HEIGHT - titleMessageC->h)/2 + 200, titleMessageC, screen);
           }
           else
           {
               //things on screen that's not at the title screen
               //the title screen messages are re-used to avoid wasting memory
               apply_surface( 0, 0, background, screen);
               
               titleMessageA = TTF_RenderText_Shaded( titleFont3, "Current Scores", blackColor, blue_color);
               titleMessageB = TTF_RenderText_Solid( titleFont3, "Options", blackColor);
               titleMessageC = TTF_RenderText_Shaded( titleFont3, "Music Info", blackColor, blue_color);
               
               std::stringstream playerOne;
               std::stringstream playerTwo;
               playerOne << "Player One - " << currentPlayerOneScore;
               playerTwo << "Player Two - " << currentPlayerTwoScore;
               playerOneScore = TTF_RenderText_Shaded( titleFont3, playerOne.str().c_str(), blackColor, background_color);
               playerTwoScore = TTF_RenderText_Shaded( titleFont3, playerTwo.str().c_str(), blackColor, background_color);
               
               apply_surface((260 - titleMessageA->w) / 2 + 380, (30 - titleMessageA->h) / 2 + 100, titleMessageA, screen);
               apply_surface((260 - titleMessageB->w) / 2 + 380, (30 - titleMessageB->h) / 2 + 195, titleMessageB, screen);
               apply_surface((260 - titleMessageC->w) / 2 + 380, (30 - titleMessageC->h) / 2 + 290, titleMessageC, screen);
               apply_surface((260 - musicText->w) / 2 + 380, (30 - musicText->h) / 2 + 385, musicText, screen);
               apply_surface((260 - playerOneScore->w) / 2 + 380, (30 - playerOneScore->h) / 2 + 135, playerOneScore, screen);
               apply_surface((260 - playerTwoScore->w) / 2 + 380, (30 - playerTwoScore->h) / 2 + 155, playerTwoScore, screen);
               apply_surface((260 - newGame->w) / 2 + 380, (30 - newGame->h) / 2 + 240, newGame, screen);
               apply_surface((130 - howPlay->w) / 2 + 510, (30 - howPlay->h) / 2 + 35, howPlay, screen);
               apply_surface((130 - about->w) / 2 + 510, (30 - about->h) / 2 + 70, about, screen);
               apply_surface((130 - version->w) / 2 + 510, (30 - version->h) / 2 + 5, version, screen);
               SDL_FreeSurface( playerOneScore );
               SDL_FreeSurface( playerTwoScore );
               
               //music buttons
               apply_surface((260 - musicStop->w) * 2 / 5 + 380, (30 - musicStop->h) / 2 + 430, musicStop, screen);
               apply_surface((260 - musicNext->w) * 4 / 5 + 380, (30 - musicNext->h) / 2 + 430, musicNext, screen);
               apply_surface((260 - musicBack->w) * 1 / 5 + 380, (30 - musicBack->h) / 2 + 430, musicBack, screen);
               
               //if the music is playing, show the pause button, otherwise show the play button
               if(musicIsPlaying)
               {
                   apply_surface((260 - musicPause->w) * 3 / 5 + 380, (30 - musicPause->h) / 2 + 430, musicPause, screen);
                   std::stringstream author;
                   author << "Artist: " << backgroundMusicAuthor[RandSong];
                   titleMessageC = TTF_RenderText_Shaded( titleFont3, author.str().c_str(), blackColor, background_color);
                   apply_surface((260 - titleMessageC->w) / 2 + 380, (30 - titleMessageC->h) / 2 + 325, titleMessageC, screen);               
                   std::stringstream track;
                   track << "Track: " << backgroundMusicTrack[RandSong];
                   titleMessageC = TTF_RenderText_Shaded( titleFont3, track.str().c_str(), blackColor, background_color);
                   apply_surface((260 - titleMessageC->w) / 2 + 380, (30 - titleMessageC->h) / 2 + 345, titleMessageC, screen);               
               }
               else
               {
                   apply_surface((260 - musicPlay->w) * 3 / 5 + 380, (30 - musicPlay->h) / 2 + 430, musicPlay, screen);                   
                   titleMessageC = TTF_RenderText_Shaded( titleFont3, "Press Play below", blackColor, background_color);
                   apply_surface((260 - titleMessageC->w) / 2 + 380, (30 - titleMessageC->h) / 2 + 325, titleMessageC, screen);               
                   titleMessageC = TTF_RenderText_Shaded( titleFont3, "to begin playback", blackColor, background_color);
                   apply_surface((260 - titleMessageC->w) / 2 + 380, (30 - titleMessageC->h) / 2 + 345, titleMessageC, screen);               
               }
               
               if ( (info == false))
               {
                    if(!checkForWin())
                    {
                        squareCheck();
                    }
                    else if(checkForWin() == 1)
                    {
                         winnerMessage = TTF_RenderText_Shaded( winnerFont, "Player 1 Wins!", green_color, background_color);
                         apply_surface((SCREEN_WIDTH - winnerMessage->w)/2 - 65, (SCREEN_HEIGHT - winnerMessage->h)/2 - 190, winnerMessage, screen);                        
                    }
                    else if(checkForWin() == 2)
                    {
                         winnerMessage = TTF_RenderText_Shaded( winnerFont, "Player 2 Wins!", green_color, background_color);
                         apply_surface((SCREEN_WIDTH - winnerMessage->w)/2 - 65, (SCREEN_HEIGHT - winnerMessage->h)/2 - 190, winnerMessage, screen);                                                 
                     }
               }
               else
               {
                    if(info_type != 0)
                    {
                    SDL_SetAlpha( background_blend, SDL_SRCALPHA | SDL_RLEACCEL, 128 );
                    apply_surface( 0, 0, background_blend, screen);
                    apply_surface(0, 0, info_bubble, screen); 
                    if( info_type == "how" )
                    {
                         howText = TTF_RenderText_Shaded( titleFont3, "How to Play...", blackColor, background_color);
                         apply_surface((SCREEN_WIDTH - howText->w)/2, (SCREEN_HEIGHT - howText->h)/2 - 133, howText, screen);
                         howText = TTF_RenderText_Shaded( titleFont3, "Two players each take turns clicking", blackColor, background_color);
                         apply_surface((SCREEN_WIDTH - howText->w)/2, (SCREEN_HEIGHT - howText->h)/2 - 55, howText, screen);
                         howText = TTF_RenderText_Shaded( titleFont3, "a box.  The first player", blackColor, background_color);
                         apply_surface((SCREEN_WIDTH - howText->w)/2, (SCREEN_HEIGHT - howText->h)/2 - 40, howText, screen);                         
                         howText = TTF_RenderText_Shaded( titleFont3, "to get four in a row, column,", blackColor, background_color);
                         apply_surface((SCREEN_WIDTH - howText->w)/2, (SCREEN_HEIGHT - howText->h)/2 - 25, howText, screen);
                         howText = TTF_RenderText_Shaded( titleFont3, "or diagonal, wins the game.", blackColor, background_color);
                         apply_surface((SCREEN_WIDTH - howText->w)/2, (SCREEN_HEIGHT - howText->h)/2 - 10, howText, screen);
                         howText = TTF_RenderText_Shaded( titleFont3, "Click \"New Game\" for another round.", blackColor, background_color);
                         apply_surface((SCREEN_WIDTH - howText->w)/2, (SCREEN_HEIGHT - howText->h)/2 + 5, howText, screen);                                                  
                         howText = TTF_RenderText_Solid( titleFont3, "Close", blackColor);
                         apply_surface((SCREEN_WIDTH - howText->w)/2, (SCREEN_HEIGHT - howText->h)/2 + 97, howText, screen);                         
                     }
                     else if( info_type == "about")
                     {
                         howText = TTF_RenderText_Shaded( titleFont3, "About this game", blackColor, background_color);
                         apply_surface((SCREEN_WIDTH - howText->w)/2, (SCREEN_HEIGHT - howText->h)/2 - 133, howText, screen);
                         howText = TTF_RenderText_Shaded( titleFont3, "This game is an extention on", blackColor, background_color);
                         apply_surface((SCREEN_WIDTH - howText->w)/2, (SCREEN_HEIGHT - howText->h)/2 - 55, howText, screen);
                         howText = TTF_RenderText_Shaded( titleFont3, "the classic Tic-Tac-Toe game.", blackColor, background_color);
                         apply_surface((SCREEN_WIDTH - howText->w)/2, (SCREEN_HEIGHT - howText->h)/2 - 40, howText, screen);
                         howText = TTF_RenderText_Shaded( titleFont3, "By changing the grid to 4x4, another", blackColor, background_color);
                         apply_surface((SCREEN_WIDTH - howText->w)/2, (SCREEN_HEIGHT - howText->h)/2 - 25, howText, screen);
                         howText = TTF_RenderText_Shaded( titleFont3, "dimension of difficulty has been added.", blackColor, background_color);
                         apply_surface((SCREEN_WIDTH - howText->w)/2, (SCREEN_HEIGHT - howText->h)/2 - 10, howText, screen);                         
                         howText = TTF_RenderText_Shaded( titleFont3, "Anyone can play, few will master.", blackColor, background_color);
                         apply_surface((SCREEN_WIDTH - howText->w)/2, (SCREEN_HEIGHT - howText->h)/2 + 30, howText, screen);                         
                         howText = TTF_RenderText_Solid( titleFont3, "Close", blackColor);
                         apply_surface((SCREEN_WIDTH - howText->w)/2, (SCREEN_HEIGHT - howText->h)/2 + 97, howText, screen); 
                     }                 

                     if( buttonCheck(info_button) != 0)
                     {
                         info = false;
                         info_type = 0;
                     }
               }
               else
               {
                   info = false;
               }
               }
           }
           
           //update the screen
           if( SDL_Flip( screen ) == -1 )
           {
               return 1;
           }
   }
   clean_up();
   return 1;
}
